package application;
import java.io.*;

/**
*	@(#) ConcreteEditor.java
*
*	Un editeur concret implementant l'interface Editor.
*
*	@see Editor
*/
public class ConcreteEditor implements Editor {
	
	/**
	*	La selection courante de l'editeur.
	*/
	private Selection selection;
	
	/**
	*	Le buffer courant de l'editeur. 
	*/
	private Buffer buffer;
	
	/**
	*	Le presse-papier courant de l'editeur.
	*/
	private ClipBoard clipboard;
	
	/**
	*	Constructeur ConcreteEditor.
	*/
	public ConcreteEditor(Selection selection, Buffer buffer, ClipBoard Clipboard) {
		this.selection=selection;
		this.buffer=buffer;
		this.clipboard=Clipboard;
	}
	
	/**
	*	@return Un Clone de la selection courante de cet editeur.
	*/
	public Selection getSelection() {
		return selection.clone();
	}
	
	/**
	*	@return Un Clone du buffer courant de cet editeur.
	*/
	public Buffer getBuffer() {
		return buffer.clone();
	}
	
	/**
	*	@return Un Clone du presse-papier courant de cet editeur.
	*/
	public ClipBoard getClipBoard() {
		return clipboard.clone();
	}
	
	/**
	*	Realise un couper.
	*/
	public void cut() {
		Integer begin=selection.getBegin();
		Integer end=selection.getEnd();
		String text=buffer.getText(begin, end);
		clipboard.setContent(text);
		buffer.erase(begin, end);
		selection.setEnd(begin);
		System.out.println("Clipoard:"+clipboard.getContent());
		System.out.println("Buffer:"+buffer.getText());
	}
	
	/**
	*	Realise un copier.
	*/
	public void copy() {
		Integer begin=selection.getBegin();
		Integer end=selection.getEnd();
		String text=buffer.getText(begin, end);
		clipboard.setContent(text);
		System.out.println("Clipoard:"+clipboard.getContent());
		System.out.println("Buffer:"+buffer.getText());
	}
	
	/**
	*	Realise un coller.
	*/
	public void paste() {	
		Integer begin=selection.getBegin();
		Integer end=selection.getEnd();
		String text=clipboard.getContent();
		System.out.println("Clipoard:"+clipboard.getContent());
		buffer.erase(begin, end);
		buffer.insert(begin, text);
		System.out.println("Buffer:"+buffer.getText());
		selection.setBegin(begin+text.length());
		selection.setEnd(begin+text.length());
	}
	
	/**
	*	Realise une selection.
	*
	*	@param begin
	*				L'indice de debut de la selection.
	*
	*	@param end
	*				L'indice de fin de la selection.
	*/
	public void select(Integer begin, Integer end) {
		selection.setBegin(begin);
		selection.setEnd(end);
	}
	
	/**
	*	Realise une insertion.
	*
	*	@param text
	*				La chaine de caracteres a inserer.
	*/
	public void insert(String text) {
		Integer begin=selection.getBegin();
		Integer end=selection.getEnd();
		buffer.erase(begin, end);
		buffer.insert(begin, text); 
		System.out.println("Buffer:"+buffer.getText());
		selection.setBegin(begin+text.length());
		selection.setEnd(begin+text.length());
	}
	
	/**
	*	Realise une suppression.
	*/
	public void delete() {
		Integer begin=selection.getBegin();
		Integer end=selection.getEnd();
		if (begin==end) {
			selection.setBegin(begin-1);
			begin=selection.getBegin();
		}
		buffer.erase(begin, end);
		selection.setEnd(begin);
		System.out.println("Buffer:"+buffer.getText());
	}
	
	/**
	*	Realise l'ouverture d'un fichier.
	*
	*	@param openedFile
	*				Le fichier a ouvrir.
	*/
	public void openFile(File openedFile) {
		BufferedReader bReader;
		String fileContent="";
		String lineContent="";
		// Hack : Cet algorithme n'est surement pas optimal. 
		try {
			bReader=new BufferedReader(new FileReader(openedFile));
			do {
				try {
					lineContent=bReader.readLine();
				} 
				catch (IOException e) {
					e.printStackTrace();
				}
				
				if (lineContent==null) {
					break;
				}
				else {
					fileContent+='\n'+lineContent;
				}
			}
			
			while (lineContent!=null); 	
		} 
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		buffer.eraseAll();
		buffer.insert(0, fileContent);
	}	
	
	/**
	*	Realise la sauvegarde dans un repertoire choisi.
	*	
	*	@param savedFile
	*				Le fichier a sauvegarder.
	*/
	public void saveAsFile(File savedFile) {
		FileWriter fWriter;
		
		try {
			fWriter=new FileWriter(savedFile);
			System.out.println(buffer.getText());
			fWriter.write(buffer.getText()); fWriter.close();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}		
	}
	
	/**
	*	@return Un memento contenant l'etat actuel de l'editeur. 
	*/
	public Memento getMemento() {
		Memento memEditor=MementoEditor.create();
		Triplet<Buffer, Selection, ClipBoard> t = new Triplet<Buffer, Selection, ClipBoard>(buffer.clone(),selection.clone(),clipboard.clone());
		State s=new State(t);
		memEditor.setState(s);
		return memEditor;
	}

	/**
	*	Restaure l'etat de cet editeur.
	*
	*	@param memento
	*				Le memento contenant l'etat a restaurer.
	*/
	public void setMemento(Memento memento) {
		Triplet<Buffer, Selection, ClipBoard> temp=(Triplet<Buffer, Selection, ClipBoard>)memento.getState().getState();
		this.buffer=temp.getFirst().clone();
		this.selection=temp.getSecond().clone();
		this.clipboard=temp.getThird().clone();
	}
	
}
